<template>
	<div class="sh-iv-form">
		<Form
			ref="ivForm"
			:model="data"
			:rules="formRules"
			:inline="inline"
			:label-position="labelPosition"
			:label-width="labelWidth"
			:show-message="showMessage"
			:autocomplete="autocomplete"
			:hide-required-mark="hideRequiredMark"
			:label-colon="labelColon"
			:disabled="disabled">
			<Row v-bind="row">
				<template v-for="(column, columnIndex) in formItems" :key="columnIndex">
					<iv-group-item :data="data" :column="column" :group-renders="groupRenders" :size="size" :span="span" :col="colProps" />
				</template>
				<Col v-if="handle" :span="span" v-bind="colProps">
					<FormItem class="form-button-item">
						<Button :size="size" type="primary" :disabled="disabled" @click="onFormSubmit">{{ btnSubmitText }}</Button>
						<Button :size="size" type="default" @click="onFormReset">{{ btnResetText }}</Button>
					</FormItem>
				</Col>
			</Row>
			<slot name="default"></slot>
			<div v-if="footer" class="sh-common-footer">
				<div class="sh-common-footer-left">
					<Space><slot name="formLeft"></slot></Space>
				</div>
				<Space class="sh-common-footer-right">
					<slot name="formRight"></slot>
					<Button v-ripple type="primary" :size="size" :disabled="disabled" @click="onFormSubmit">{{ btnSubmitText }}</Button>
					<Button v-ripple type="default" :size="size" @click="onFormReset">{{ btnResetText }}</Button>
				</Space>
			</div>
		</Form>
	</div>
</template>

<script>
import ivGroupItem from './components/iv-group-item.vue'
export default {
	name: 'ShIvForm',
	components: {
		ivGroupItem
	},
	provide() {
		return {
			shivform: this
		}
	},
	props: {
		data: {
			type: Object,
			default() {
				return {}
			}
		},
		items: {
			type: Array,
			default() {
				return []
			}
		},
		rules: {
			type: Object,
			default() {
				return {}
			}
		},
		inline: {
			type: Boolean
		},
		labelPosition: {
			type: String
		},
		labelWidth: {
			type: Number,
			default: 100
		},
		showMessage: {
			type: Boolean,
			default: true
		},
		autocomplete: {
			type: String
		},
		hideRequiredMark: {
			type: Boolean
		},
		labelColon: {
			type: Boolean
		},
		disabled: {
			type: Boolean
		},
		footer: {
			type: Boolean,
			default: false
		},
		size: {
			type: String,
			default: 'default'
		},
		row: {
			type: Object,
			default() {
				return {
					gutter: 20
				}
			}
		},
		span: {
			type: Number,
			default: 24
		},
		handle: {
			type: Boolean,
			default: false
		},
		valid: {
			type: Boolean,
			default: true
		},
		btnSubmitText: {
			type: String,
			default: '确认'
		},
		btnResetText: {
			type: String,
			default: '取消'
		}
	},
	emits: ['submit', 'reset', 'item-change'],
	data() {
		return {
			formItems: [],
			formRules: {},
			groupRenders: {
				CheckboxGroup: 'Checkbox',
				RadioGroup: 'Radio',
				Select: 'Option'
			},
			renderRelationship: {
				Tree: 'TreeSelect',
				Time: 'DatePicker',
				TextArea: 'Input',
				Checkgroup: 'CheckboxGroup',
				Radiogroup: 'RadioGroup'
			}
		}
	},
	computed: {
		colProps() {
			return this.inline ? { xs: 24, sm: 12, md: 12, lg: 8, xl: 8 } : {}
		}
	},
	watch: {
		items: {
			handler() {
				this.initItemsConfig()
			},
			deep: true
		},
		rules: {
			handler(newvalue, oldValue) {
				this.initEditRules(newvalue)
			},
			deep: true,
			immediate: true
		}
	},
	created() {
		this.initItemsConfig()
	},
	mounted() {},
	methods: {
		formRef() {
			return this.$refs.ivForm
		},
		async validate() {
			return this.formRef().validate()
		},
		async onFormSubmit() {
			let validateResult = await this.validate()
			if (!validateResult) return
			this.$emit('submit', this.data)
		},
		onFormReset() {
			this.formRef().resetFields()
			this.$emit('reset', this.data)
		},
		// 根据规则重新初始化字段配置
		initItemsConfig() {
			const that = this
			if (that.items && that.items.length > 0) {
				let formItems = that.$vUtils.clone(that.items, true)
				let fieldRules = {}
				that.$vUtils.eachTree(formItems, item => {
					let renderProps = item.renderProps || {}
					item.renderName = that.getRenderName(item.renderName, renderProps)
					item.prop = item.prop || item.field
					item.label = item.label || item.title
					delete item.field
					delete item.title
					let arrayModelRenders = ['Cascader', 'Transfer', 'TagSelect', 'CheckboxGroup']
					if (item.prop && !that.$vUtils.has(that.data, item.prop)) {
						that.$vUtils.set(that.data, item.prop, renderProps.defaultValue || (arrayModelRenders.includes(item.renderName) ? [] : ''))
					}
					if (item.prop && +item.renderRequire) {
						let dataType = 'string'
						let arrayType = ['CheckboxGroup']
						if (arrayType.includes(item.renderName) || (item.renderName === 'Select' && renderProps.multiple)) {
							dataType = 'array'
						}
						fieldRules[item.prop] = [{ required: true, message: that.getDefaultMessage(item.renderName, item.label), type: dataType }]
					}
				})
				that.formItems = formItems
				that.initEditRules(fieldRules)
			}
		},
		// 初始化验证规则
		initEditRules(rules) {
			const that = this
			if (rules && that.$vUtils.isPlainObject(rules)) {
				Object.keys(rules).forEach(key => {
					if (that.formRules[key]) {
						that.formRules[key] = Array.from(new Set(that.formRules[key].concat(rules[key])))
					} else {
						that.formRules[key] = rules[key]
					}
				})
			}
		},
		// 获取渲染器关系
		getRenderName(renderName, props) {
			if (renderName && renderName.startsWith('$v')) {
				let reRender = renderName.replace('$v', '')
				let relationRender = this.renderRelationship[reRender]
				return relationRender || reRender
			}
			return renderName || 'Input'
		},
		// 获取默认验证信息
		getDefaultMessage(renderType, title) {
			const selectRenders = ['Switch', 'Select', 'TreeSelect', 'DatePicker', 'TimePicker', 'Cascader', 'City', 'Rate']
			return (selectRenders.includes(renderType) ? '请选择' : '请输入') + title
		}
	}
}
</script>

<style scoped></style>
